type JSDynamicObject = any;
function accurateInterval (func : any, interval : number, opts : JSDynamicObject) : JSDynamicObject {
    if (! opts) opts = {};
    var clear ! : () => void;
    var nextAt ! : number;
    var timeout ! : null | number;
    var wrapper ! : any;
    var now : number = new Date ().getTime ();
    nextAt = now;
    if (opts.aligned) {
        nextAt += interval - now % interval;
    }
    if (! opts.immediate) {
        nextAt += interval;
    }
    timeout = null;
    wrapper = function wrapper () : void {
        var scheduledTime : number = nextAt;
        nextAt += interval;
        timeout = setTimeout (wrapper, nextAt - new Date ().getTime ());
        func (scheduledTime);
    }
    ;
    clear = function clear () : void {
        return clearTimeout (timeout);
    }
    ;
    timeout = setTimeout (wrapper, nextAt - new Date ().getTime ());
    return {
        clear : clear
    };
}
;
console.log ('Start time:  ' + Date.now ());
var foo : JSDynamicObject = accurateInterval (function (scheduledTime : any) : void {
    console.log ('Actual time: ' + Date.now () + ' -- Scheduled time: ' + scheduledTime);
}, 2000, {
    aligned : true,
    immediate : true
});
setTimeout (function () : void {
    foo.clear ();
}, 10000);
